//
// Created by yongj on 2021/7/29.
//

#ifndef MCP2515_MCP2515_H
#define MCP2515_MCP2515_H

#include "pico.h"
#include "pico/time.h"
#include "hardware/spi.h"
#include "pico/binary_info.h"
#include "pico/stdlib.h"
#include "stdio.h"
#include "mcp2515_can_dfs.h"
#include "hardware/timer.h"

#define CAN_NOMSG           (4)

#define MCP_8MHz    8
#define MCP_12MHz   12
#define MCP_16MHz   16

#define CAN_5KBPS   5
#define CAN_10KBPS  10
#define CAN_20KBPS  20
#define CAN_25KBPS  25
#define CAN_31K25BPS    31
#define CAN_33KBPS  33
#define CAN_40KBPS  40
#define CAN_50KBPS  50
#define CAN_80KBPS  80
#define CAN_83K3BPS 83
#define CAN_95KBPS  95
#define CAN_100KBPS 100
#define CAN_125KBPS 125
#define CAN_200KBPS 200
#define CAN_250KBPS 250
#define CAN_500KBPS 500
#define CAN_666KBPS 666
#define CAN_800KBPS 800
#define CAN_1000KBPS 1000

void MCP2515_Pin_init();

/*********************************************************************************************************
** Function name:           mcp2515_init
** Descriptions:            init the device
*********************************************************************************************************/
uint8_t mcp2515_init(uint16_t canSpeed, uint8_t clock);

/*********************************************************************************************************
** Function name:           mcp2515_reset
** Descriptions:            reset the device
*********************************************************************************************************/
void mcp2515_reset(void);

/*********************************************************************************************************
** Function name:           mcp2515_setCANCTRL_Mode
** Descriptions:            set control mode
*********************************************************************************************************/
uint8_t mcp2515_setCANCTRL_Mode(uint8_t newmode);

/*********************************************************************************************************
** Function name:           mcp2515_readRegister
** Descriptions:            read register
*********************************************************************************************************/
uint8_t mcp2515_readRegister(uint8_t address);

/*********************************************************************************************************
** Function name:           getMode
** Descriptions:            Returns current control mode
*********************************************************************************************************/
uint8_t getMode();

/*********************************************************************************************************
** Function name:           mcp2515_modifyRegister
** Descriptions:            set bit of one register
*********************************************************************************************************/
void mcp2515_modifyRegister(uint8_t address, uint8_t mask, uint8_t data);

/*********************************************************************************************************
** Function name:           mcp2515_requestNewMode
** Descriptions:            Set control mode
*********************************************************************************************************/
uint8_t mcp2515_requestNewMode(uint8_t newmode);

/*********************************************************************************************************
** Function name:           mcp2515_configRate
** Descriptions:            set baudrate
*********************************************************************************************************/
uint8_t mcp2515_configRate(uint16_t canSpeed, uint8_t clock);

/*********************************************************************************************************
** Function name:           mcp2515_setRegister
** Descriptions:            set register
*********************************************************************************************************/
void mcp2515_setRegister(uint8_t address, uint8_t value);

/*********************************************************************************************************
** Function name:           mcp2515_initCANBuffers
** Descriptions:            init canbuffers
*********************************************************************************************************/
void mcp2515_initCANBuffers(void);

/*********************************************************************************************************
** Function name:           setMode
** Descriptions:            Sets control mode
*********************************************************************************************************/
uint8_t setMode(uint8_t opMode);

/*********************************************************************************************************
** Function name:           init_Mask
** Descriptions:            init canid Masks
*********************************************************************************************************/
uint8_t init_Mask(uint8_t num, uint8_t ext, unsigned long ulData);

/*********************************************************************************************************
** Function name:           mcp2515_write_id
** Descriptions:            write can id
*********************************************************************************************************/
void mcp2515_write_id(uint8_t mcp_addr, uint8_t ext, unsigned long id);

/*********************************************************************************************************
** Function name:           mcp2515_id_to_buf
** Descriptions:            configure tbufdata[4] from id and ext
*********************************************************************************************************/
void mcp2515_id_to_buf(uint8_t ext, unsigned long id, uint8_t* tbufdata);

/*********************************************************************************************************
** Function name:           mcp2515_setRegisterS
** Descriptions:            set registerS
*********************************************************************************************************/
void mcp2515_setRegisterS(uint8_t address, uint8_t values[], uint8_t n);

/*********************************************************************************************************
** Function name:           init_Filt
** Descriptions:            init canid filters
*********************************************************************************************************/
uint8_t init_Filt(uint8_t num, uint8_t ext, unsigned long ulData);


/*********************************************************************************************************
** Function name:           mcp2515_read_canMsg
** Descriptions:            read message
*********************************************************************************************************/
void mcp2515_read_canMsg(uint8_t buffer_load_addr, volatile unsigned long* id, volatile uint8_t* ext,
                         volatile uint8_t* rtrBit, volatile uint8_t* len, volatile uint8_t* buf);

/*********************************************************************************************************
** Function name:           mcp2515_write_canMsg
** Descriptions:            write msg
**                          Note! There is no check for right address!
*********************************************************************************************************/
void mcp2515_write_canMsg(uint8_t buffer_sidh_addr, unsigned long id, uint8_t ext, uint8_t rtrBit, uint8_t len,
                          volatile uint8_t* buf);


/*********************************************************************************************************
** Function name:           txSidhToTxLoad
** Descriptions:            return tx load command according to tx buffer sidh register
*********************************************************************************************************/
uint8_t txSidhToRTS(uint8_t sidh);

/*********************************************************************************************************
** Function name:           txSidhToTxLoad
** Descriptions:            return tx load command according to tx buffer sidh register
*********************************************************************************************************/
uint8_t txSidhToTxLoad(uint8_t sidh);

/*********************************************************************************************************
** Function name:           mcp2515_start_transmit
** Descriptions:            Start message transmit on mcp2515
*********************************************************************************************************/
void mcp2515_start_transmit(uint8_t mcp_addr);

#endif //MCP2515_MCP2515_H
